<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Composites revisited</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="actors_revisited.html">
<link rel="next" href="operators_revisited.html">
</head>
<body>
<table width="100%" height="48" border="0" background="theme/bkd2.gif" cellspacing="2">
  <tr>
    <td width="10">
    </td>
    <td width="85%">
      <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Composites revisited</b></font>
    </td>
    <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" align="right" border="0"></a></td>
  </tr>
</table>
<br>
<table border="0">
  <tr>
    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
    <td width="30"><a href="actors_revisited.html"><img src="theme/l_arr.gif" border="0"></a></td>
    <td width="20"><a href="operators_revisited.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
</table>
<p>
A composite is an actor base class composed of zero or more actors (see actor) and an operation. A composite is itself an actor superclass and conforms to its expected conceptual interface. Its eval member function un-funnels the tupled actual arguments by invoking each of the actors' eval member function. The results of each are then passed on as arguments to the operation. Specializations are provided for composites that handle different numbers of actors from zero to N, where N is a predefined maximum.</p>
<p>
Schematically:</p>
<code><pre>
    <span class=identifier>actor0</span><span class=special>.</span><span class=identifier>eval</span><span class=special>(</span><span class=identifier>tupled_args</span><span class=special>) --&gt; </span><span class=identifier>arg0 </span><span class=special>--&gt; |
    </span><span class=identifier>actor1</span><span class=special>.</span><span class=identifier>eval</span><span class=special>(</span><span class=identifier>tupled_args</span><span class=special>) --&gt; </span><span class=identifier>arg1 </span><span class=special>--&gt; |
    </span><span class=identifier>actor2</span><span class=special>.</span><span class=identifier>eval</span><span class=special>(</span><span class=identifier>tupled_args</span><span class=special>) --&gt; </span><span class=identifier>arg3 </span><span class=special>--&gt; | --&gt; </span><span class=identifier>operation</span><span class=special>(</span><span class=identifier>arg0</span><span class=special>...</span><span class=identifier>argN</span><span class=special>)
    ...                                   |
    </span><span class=identifier>actorN</span><span class=special>.</span><span class=identifier>eval</span><span class=special>(</span><span class=identifier>tupled_args</span><span class=special>) --&gt; </span><span class=identifier>argN </span><span class=special>--&gt; |
</span></pre></code>
<p>
Here's a typical example of the composite's eval member function for a 2-actor composite:</p>
<code><pre>
    <span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>TupleT</span><span class=special>&gt;
    </span><span class=keyword>typename </span><span class=identifier>actor_result</span><span class=special>&lt;</span><span class=identifier>self_t</span><span class=special>, </span><span class=identifier>TupleT</span><span class=special>&gt;::</span><span class=identifier>type
    </span><span class=identifier>eval</span><span class=special>(</span><span class=identifier>TupleT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>args</span><span class=special>) </span><span class=keyword>const
    </span><span class=special>{
        </span><span class=keyword>typename </span><span class=identifier>actor_result</span><span class=special>&lt;</span><span class=identifier>A0</span><span class=special>, </span><span class=identifier>TupleT</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>r0 </span><span class=special>= </span><span class=identifier>a0</span><span class=special>.</span><span class=identifier>eval</span><span class=special>(</span><span class=identifier>args</span><span class=special>);
        </span><span class=keyword>typename </span><span class=identifier>actor_result</span><span class=special>&lt;</span><span class=identifier>A1</span><span class=special>, </span><span class=identifier>TupleT</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>r1 </span><span class=special>= </span><span class=identifier>a1</span><span class=special>.</span><span class=identifier>eval</span><span class=special>(</span><span class=identifier>args</span><span class=special>);
        </span><span class=keyword>return </span><span class=identifier>op</span><span class=special>(</span><span class=identifier>r0</span><span class=special>, </span><span class=identifier>r1</span><span class=special>);
    }
</span></pre></code>
<p>
where self_t is the composite's 'self' type, TupleT 'args' is the tuple-packed arguments passed to the actor (see actor) and op is the operation associated with the composite. r0 and r1 are the actual arguments un-funneled from 'args' and pre-processed by the composite's actors which are then passed on to the operation 'op'.</p>
<p>
The operation can be any suitable functor that can accept the arguments passed in by the composite. The operation is expected to have a member operator() that carries out the actual operation. There should be a one to one correspondence between actors of the composite and the arguments of the operation's member operator().</p>
<p>
The operation is also expected to have a nested template class result&lt;T0...TN&gt;. The nested template class result should have a typedef 'type' that reflects the return type of its member operator(). This is essentially a type computer that answers the metaprogramming question &quot;Given arguments of type T0...TN, what will be your operator()'s return type?&quot;. There is a special case for operations that accept no arguments. Such nullary operations are only required to define a typedef result_type that reflects the return type of its operator().</p>
<p>
Here's a view on what happens when the eval function is called:</p>
<code><pre>
    <span class=identifier>tupled </span><span class=identifier>arguments</span><span class=special>:                 </span><span class=identifier>args
                                       </span><span class=special>|
                       +-------+-------+-------+-------+
                       |       |       |       |       |
                       |       |       |       |       |
    </span><span class=identifier>actors</span><span class=special>:         </span><span class=identifier>actor0  </span><span class=identifier>actor1  </span><span class=identifier>actor2  </span><span class=identifier>actor3</span><span class=special>..</span><span class=identifier>actorN
                       </span><span class=special>|       |       |       |       |
                       |       |       |       |       |
    </span><span class=identifier>operation</span><span class=special>:   </span><span class=identifier>op</span><span class=special>( </span><span class=identifier>arg0</span><span class=special>,   </span><span class=identifier>arg1</span><span class=special>,   </span><span class=identifier>arg2</span><span class=special>,   </span><span class=identifier>arg3</span><span class=special>,...</span><span class=identifier>argN </span><span class=special>)
                  |
                  |
    </span><span class=identifier>returns</span><span class=special>:      +---&gt; </span><span class=identifier>operation</span><span class=special>::</span><span class=identifier>result</span><span class=special>&lt;</span><span class=identifier>T0</span><span class=special>...</span><span class=identifier>TN</span><span class=special>&gt;::</span><span class=identifier>type
</span></pre></code>
<p>
Here's an example of a simple operation that squares a number:</p>
<code><pre>
    <span class=keyword>struct </span><span class=identifier>square </span><span class=special>{

        </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ArgT</span><span class=special>&gt;
        </span><span class=keyword>struct </span><span class=identifier>result </span><span class=special>{ </span><span class=keyword>typedef </span><span class=identifier>ArgT </span><span class=identifier>type</span><span class=special>; };

        </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ArgT</span><span class=special>&gt;
        </span><span class=identifier>ArgT </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>ArgT </span><span class=identifier>n</span><span class=special>) </span><span class=keyword>const </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>n </span><span class=special>* </span><span class=identifier>n</span><span class=special>; }
    };
</span></pre></code>
<p>
This is a perfect example of a polymorphic functor discussed before in the section on functions. As we can see, operations are polymorphic. Its arguments and return type are not fixed to a particular type. The example above for example, can handle any ArgT type as long as it has a multiplication operator.</p>
<p>
Composites are not created directly. Instead, there are meta- programs provided that indirectly create composites. See operators, binders and functions for examples.</p>
<table border="0">
  <tr>
    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
    <td width="30"><a href="actors_revisited.html"><img src="theme/l_arr.gif" border="0"></a></td>
    <td width="20"><a href="operators_revisited.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
</table>
<br>
<hr size="1">
<p class="copyright">Copyright &copy; 2001-2002 Joel de Guzman<br>
  <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt) </font> </p>
</body>
</html>
